/*************************************************************************
 * Copyright (C) [2018] by Cambricon, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *************************************************************************/

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h> // 确保包含了这个头文件
#include <string.h>
#include <cndev.h>
#ifndef WIN32
#include <sys/sysinfo.h>
#endif

void DevInit(void)
{
  cndevRet_t ret = cndevInit(0);
  if (CNDEV_SUCCESS != ret) {
    printf("cndev init failed: %s.\n", cndevGetErrorString(ret));
  }
}

void DevRelease(void)
{
  cndevRelease();
}

cndevDevice_t MLU_init(unsigned int index)
{
  cndevDevice_t devHandle;
  cndevRet_t ret = cndevGetDeviceHandleByIndex(index, &devHandle);
  cndevCheckErrors(ret);
  return devHandle;
}

const char* GetDevName(cndevDevice_t devHandle)
{
    cndevCardName_t nameInfo;
    nameInfo.version = CNDEV_VERSION_5;
    // get cardname by devId
    const char* Name = cndevGetCardNameStringByDevId(devHandle);
    return Name;
}

char* GetCardSN(cndevDevice_t devHandle)
{
    //get card[x]'s SN
    cndevCardSN_t cardSN;
    cardSN.version = CNDEV_VERSION_5;
    cndevCheckErrors(cndevGetCardSN(&cardSN, devHandle));
    //printf("The SN of the card: %012lx\n", cardSN.sn);
    __uint64_t hex_number = cardSN.sn;
    char buffer[2 * sizeof(hex_number) + 1];
    snprintf(buffer, sizeof(buffer), "%012lX", hex_number);
    char* hex_string  = buffer;
    return hex_string;
}

unsigned int  GetTotalMemoryInfo(cndevDevice_t devHandle)
{
    // get card[x]'s memory info
    cndevMemoryInfo_t memInfo;
    memInfo.version = CNDEV_VERSION_5;
    cndevCheckErrors(cndevGetMemoryUsage(&memInfo, devHandle));
    return memInfo.physicalMemoryTotal;
}

unsigned int  GetUsedMemoryInfo(cndevDevice_t devHandle)
{
    // get card[x]'s memory info
    cndevMemoryInfo_t memInfo;
    memInfo.version = CNDEV_VERSION_5;
    cndevCheckErrors(cndevGetMemoryUsage(&memInfo, devHandle));
    return memInfo.physicalMemoryUsed;
}

unsigned int GetPowerUsage(cndevDevice_t devHandle)
{
    // get card[x]'s power usage info
    cndevPowerInfo_t powerInfo;
    powerInfo.version = CNDEV_VERSION_5;
    cndevCheckErrors(cndevGetPowerInfo(&powerInfo, devHandle));
    return powerInfo.usage;
}

unsigned int GetUtilization(cndevDevice_t devHandle)
{
    // get card[x]'s MLU utilization
    cndevUtilizationInfo_t utilInfo;
    utilInfo.version = CNDEV_VERSION_5;
    cndevCheckErrors(cndevGetDeviceUtilizationInfo(&utilInfo, devHandle));
    return utilInfo.averageCoreUtilization;
}
